package com.cmwa.scbp.base.mvc.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cmwa.scbp.base.constants.Constant;
import com.cmwa.scbp.base.constants.SysProp;
import com.cmwa.scbp.base.mvc.entity.Employee;
import com.cmwa.scbp.base.mvc.entity.Result;
import com.cmwa.scbp.sys.client.Client;
import com.cmwa.scbp.sys.client.ClientManager;
import com.cmwa.scbp.sys.menu.service.MenuService;
import com.cmwa.scbp.sys.userInfo.entity.UserInfoVo;
import com.cmwa.scbp.sys.userInfo.service.UserInfoService;
import com.cmwa.scbp.utils.PwdUtil;
import com.cmwa.scbp.utils.SessionUtils;
import com.cmwa.scbp.utils.ad.ADcheck;
import com.cmwa.scbp.utils.cached.EmployeeCached;

@Controller
@RequestMapping("/index")
public class IndexController extends BaseController {
	private static Logger log = LoggerFactory.getLogger(IndexController.class);
	@Resource
	private MenuService menuService;
	@Resource
	private UserInfoService userInfoService;

	@Resource
	private SysProp sysProp;
	
	@RequestMapping("/error/{errorCode}")
	public String error(@PathVariable("errorCode") String errorCode) {
		return "system/hint/" + errorCode;
	}

	/**
	 * 系统首页页面
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/indexView")
	public String indexView(ModelMap model) {
		Employee user = SessionUtils.getEmployee();
		if (user != null) {
			model.addAttribute("currentEmpId", user.getID());
			model.addAttribute("menuMap", menuService.buildMenuMap(user));

			String userType = user.getEmpType();
			String empId = user.getID();
			String belongSystem = Constant.BELONG_SYSTEM_1;
			
			// 外部人员不能访问后台系统
			if (StringUtils.equals("OUT", userType)) {
				return "system/hint/nonPrivileged";
			} else if (StringUtils.equals("IN", userType)) {
				// 判断是否有系统管理权限
				List<String> authMenus = menuService.queryAuthMenuByEmpId(empId,belongSystem);
				if (CollectionUtils.isEmpty(authMenus)) {// 内部人员，但无系统菜单权限
					return "system/hint/nonPrivileged";
				}
			}
		}

		model.addAttribute("indexMsgViewf", "1000");
		model.addAttribute("indexMsgBacklogf", "1000");
		model.addAttribute("indexMsgMonitorf", "1000");
		model.addAttribute("firstMsgViewf", "1000");
		model.addAttribute("firstMsgBacklogf", "1000");
		model.addAttribute("firstMsgMonitorf", "1000");

		SimpleDateFormat str = new SimpleDateFormat("yyyy-MM-dd");
		model.addAttribute("nowDate", str.format(new Date()));// 传入系统今天的日期，刷新监控时对比
		return "system/index/index";
	}

	/**
	 * 提示无权限页面
	 * 
	 */
	@RequestMapping("/nonPrivilegedView")
	public String nonPrivilegedView(@RequestParam(value = "type", required = false) String type,
			@RequestParam(value = "redireUrl", required = false) String redireUrl, Model model) {
		model.addAttribute("type", type);
		model.addAttribute("redireUrl", redireUrl);
		return "system/hint/nonPrivileged";
	}

	/**
	 * 登录页面
	 * 
	 * @author ex-hejm
	 * @date 2018年10月25日 下午7:17:32
	 * @return
	 */
	@RequestMapping("/loginPage")
	public String loginPage(ModelMap map) {
		map.addAttribute("r", new Date().getTime());
		// 清空线程中的用户信息
		SessionUtils.setEmployee(null);
		return "system/index/login";
	}

	/**
	 * 默认面
	 * 
	 * @author ex-hejm
	 * @date 2018年11月9日 下午3:03:06
	 * @return
	 */
	@RequestMapping("/defaultPage")
	public String defaultPage() {
		return "defaultPage";
	}

	@RequestMapping("/logout")
	public void logout(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException {
		request.getSession().invalidate();
		// 清空线程中的用户信息
		SessionUtils.setEmployee(null);
		response.sendRedirect(sysProp.getLoginUrl());
	}

	@RequestMapping("/login")
	@ResponseBody
	public Result<Object> login(@RequestParam("loginName") String loginName, @RequestParam("loginPwd") String loginPwd,
			@RequestParam("verifyCode") String verifyCode, HttpServletRequest request)
			throws UnsupportedEncodingException {
		Result<Object> result = new Result<Object>();

		Object captcha = request.getSession().getAttribute(Constant.CAPTCHA);
		if (captcha == null) {
			log.error("验证码已失效！");
			result.setSuccess(false);
			result.setMessage("验证码已失效！");
		} else if (!StringUtils.equalsIgnoreCase(verifyCode, String.valueOf(captcha))) {
			log.error("验证码输入错误！");

			result.setSuccess(false);
			result.setMessage("验证码输入错误！");
		} else {
			request.getSession().removeAttribute(Constant.CAPTCHA);
			result = changeLoginMethod(loginName, loginPwd, request);
		}
		return result;
	}

	/**
	 * ad域认证
	 * 
	 * @author ex-hejm
	 * @param loginPwd
	 * @param loginName
	 * @date 2018年10月25日 下午5:13:08
	 */
	private Result<Object> gotoAdAuth(String loginName, String loginPwd) {
		Result<Object> result = new Result<Object>();
		ADcheck adcheck = new ADcheck();
		log.info("域登录开始：--loginName:" + loginName);

		if (adcheck.winADLoginAction(loginName, loginPwd)) {
			result.setSuccess(true);
		} else {
			result.setSuccess(false);
		}
		// result.setMessage(adcheck.getRetmsg());
		result.setMessage("用户不存在或密码错误，登录失败！");
		return result;
	}

	private Result<Object> changeLoginMethod(String loginName, String loginPwd, HttpServletRequest request)
			throws UnsupportedEncodingException {
		Result<Object> result = new Result<Object>();

		HttpSession session = request.getSession();
		Employee employee = new Employee();

		List<UserInfoVo> users = EmployeeCached.getUserInfoByEmpNameorLoginName(loginName);

		if (CollectionUtils.isEmpty(users)) {
			result.setSuccess(false);
			result.setMessage("用户不存在或密码错误，登录失败！");
			log.error("从缓存中查询不到此用户");
			return result;
		}

		UserInfoVo user = users.get(0);

		if (!"STAR".equals(user.getEmpStat())) {
			result.setSuccess(false);
			result.setMessage("用户不存在或密码错误，登录失败！");
			log.error("此用户已被注销");
			return result;
		}

		if (user.isDue()) {
			result.setSuccess(false);
			result.setMessage("用户已过期，登录失败！");
			log.error("此用户已过期");
			return result;
		}

		boolean toDbValid = false; // 是否走密码登录
		if ("OUT".equals(user.getEmpType())) { // 外部员工，走密码验证
			toDbValid = true;
		} else { // 内部员工，AD登录
			String sysEnv = sysProp.getEnvironment();
			if (Constant.SYSTEM_ENVIRONMENT_P.equals(sysEnv) || StringUtils.isBlank(sysEnv)) { // 生产上，走ad
				result = gotoAdAuth(loginName, loginPwd);
				if (!result.isSuccess()) {
					return result;
				}
			} else { // 非生产，走密码
				toDbValid = true;
			}
		}

		if (toDbValid) {
			UserInfoVo dbUser = userInfoService.getUserInfoLogin(loginName);

			PwdUtil encoderMd5 = new PwdUtil(loginName, PwdUtil.STRATEGY_MD5);
			String encodePwd = encoderMd5.encode(loginPwd);
			if (!StringUtils.equals(encodePwd, dbUser.getPassword())) { // 账号或密码错误
				result.setSuccess(false);
				result.setMessage("用户不存在或密码错误，登录失败！");
				log.error("密码错误");
				return result;
			}
		}

		copyUserInfoToEmployee(employee, user);

		session.setAttribute(SessionUtils.SESSION_EMPLOYEE, employee);

		result.setSuccess(true);
		result.setMessage("登录成功");

		// 客户端菜单管理的缓存类
		Client client = new Client();
		client.setEmployee(employee);
		ClientManager.getInstance().addClinet(session.getId(), client);

		return result;
	}

	/**
	 * 复制属性
	 * 
	 * @author ex-hejm
	 * @date 2019年3月4日下午1:50:12
	 * @param employee
	 * @param user
	 */
	private void copyUserInfoToEmployee(Employee employee, UserInfoVo user) {
		employee.setID(user.getEmpID());
		employee.setName(user.getEmpName());
		employee.setLogin(user.getLogin());
		employee.setEmpType(user.getEmpType());
		employee.setOrgName(user.getOrgName());
		employee.setEmpStat(user.getEmpStat());
		employee.setCompany(user.getCompany());
		employee.setCompanyName(user.getCompanyName());
		employee.setDueDate(user.getDueDate());
	}

}
